package com.atguigu.dga230301.ds.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.dga230301.ds.bean.TDsTaskDefinition;
import com.atguigu.dga230301.ds.mapper.TDsTaskDefinitionMapper;
import com.atguigu.dga230301.ds.service.TDsTaskDefinitionService;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhangjunyi
 * @since 2023-07-04
 */
@Service
@DS("ds")
public class TDsTaskDefinitionServiceImpl extends ServiceImpl<TDsTaskDefinitionMapper, TDsTaskDefinition> implements TDsTaskDefinitionService {

    @Override
    public Map<String, TDsTaskDefinition> getTDsTaskDefinitionByDt(String assessDate, List<String> allTablesName) {
        //1.获取需要考评的表的任务定义信息并且是考评日期运行过的任务定义
        List<TDsTaskDefinition> tDsTaskDefinitionList = list(new QueryWrapper<TDsTaskDefinition>().in("name", allTablesName).exists("select 1 from t_ds_task_instance ti where code=ti.task_code and date_format(start_time,'%Y-%m-%d')='" + assessDate+"'"));

        //创建Map集合将key设置为库名.表名  value对应的任务定义数据
        HashMap<String, TDsTaskDefinition> stringTDsTaskDefinitionHashMap = new HashMap<>();

        for (TDsTaskDefinition tDsTaskDefinition : tDsTaskDefinitionList) {
            //1.获取到包含sql的列
            String taskParamsJson = tDsTaskDefinition.getTaskParams();
            //2.将Json字符串转为JSONObject
            JSONObject jsonObject = JSON.parseObject(taskParamsJson);
            //3.获取到rawScript 因为sql在这里面有定义
            String rawScript = jsonObject.getString("rawScript");
            String sql=getSqlString(rawScript);
            tDsTaskDefinition.setSql(sql);
            stringTDsTaskDefinitionHashMap.put(tDsTaskDefinition.getName(), tDsTaskDefinition);
        }

        return stringTDsTaskDefinitionHashMap;
    }

    private static String getSqlString(String rawScript) {
        //"#!/bin/bash\n\nsql=\"\nset hive.exec.dynamic.partition.mode=nonstrict; insert overwrite table gmall.dws_trade_user_payment_1d partition(dt='${do_date}')\nselect\n    user_id,\n    count(distinct(order_id)),\n    sum(sku_num),\n    sum(split_payment_amount)\nfrom gmall.dwd_trade_pay_detail_suc_inc\nwhere dt='${do_date}'\ngroup by user_id;\n\"\n\nhive -e \"$sql\""

        //with .... insert.... select.... ;"

        //4.切分字符串 获取到sql
        Integer startIndex = -1;
        Integer endIndex = -1;
        //判断是否有 with
        startIndex = rawScript.indexOf("with");

        if (startIndex==-1){
            //没有with 那么就是insert开头的的
            startIndex = rawScript.indexOf("insert");
        }



        int semicolonIdx = rawScript.indexOf(";", startIndex);
        int qouteIdx = rawScript.indexOf("\"", startIndex);

        //如果分号和双引号都存在那么获取最小（离sql最近的）的那个索引
        if (semicolonIdx>0&&qouteIdx>0){
            endIndex = Math.min(semicolonIdx, qouteIdx);
        }else {
            //如果其中有一个不存在 那么就存在的那个标点符号的下标
            endIndex = Math.max(startIndex, qouteIdx);
        }

        String sql = rawScript.substring(startIndex, endIndex);


        return sql;
    }

    public static void main(String[] args) {
        //测试
        String sqlString = getSqlString("#!/bin/bash\n\nsql=\"\ninsert overwrite table gmall.dwd_user_register_inc partition(dt='${do_date}')\nselect\n    ui.user_id,\n    date_format(create_time,'yyyy-MM-dd') date_id,\n    create_time,\n    channel,\n    province_id,\n    version_code,\n    mid_id,\n    brand,\n    model,\n    operate_system\nfrom\n(\n    select\n        data.id user_id,\n        data.create_time\n    from gmall.ods_user_info_inc\n    where dt='${do_date}'\n    and type='insert'\n)ui\nleft join\n(\n    select\n        common.ar province_id,\n        common.ba brand,\n        common.ch channel,\n        common.md model,\n        common.mid mid_id,\n        common.os operate_system,\n        common.uid user_id,\n        common.vc version_code\n    from gmall.ods_log_inc\n    where dt='${do_date}'\n    and page.page_id='register'\n    and common.uid is not null\n)log\non ui.user_id=log.user_id;\n\"\n\nhive -e \"$sql\"");

        System.out.println(sqlString);
    }
}
